#include <Windows.h>
#include <tchar.h>
#include "resource.h"
#pragma comment(lib, "Version.lib")

void AddTextToEdit(HWND hEdit, TCHAR* szFormat, ...)
{
	va_list vaList;
	va_start(vaList, szFormat);
	TCHAR szContent[1024 * 10];
	GetWindowText(hEdit, szContent, _countof(szContent));
	_vstprintf(_tcschr(szContent, 0), szFormat, vaList);
	SetWindowText(hEdit, szContent);
	va_end(vaList);

	return;
}

void LoadModule(const TCHAR* szExePath, HWND hEdit)
{
	struct SLangCodePage {
		WORD wLanguage;
		WORD wCodePage;
	};

	const TCHAR* szVerItems[] = { 
		_T("ProductLanguage"),
		_T("ProductVersion"),
		_T("ProductName"),
		_T("CompanyName"), 
		_T("LegalCopyright"),
		_T("InternalName"),
		_T("FileVersion"),
		_T("FileDescription"), 
		_T("Comments"), 
		_T("LegalTrademarks"), 
		_T("OriginalFilename"), 
		_T("PrivateBuild"), 
		_T("SpecialBuild")
	};  
		   
	HMODULE hModule = LoadLibrary(szExePath);
	if (NULL != hModule)
	{
		DWORD dwSize			= 0;
		SLangCodePage* pLangCP	= NULL;
		UINT nTranslationLen	= 0;
		UINT nBlockLen			= GetFileVersionInfoSize(szExePath, &dwSize);
		BYTE* pszBlock			= new BYTE[nBlockLen];
		GetFileVersionInfo(szExePath, NULL, nBlockLen, pszBlock);
		VerQueryValue(pszBlock, _T("\\VarFileInfo\\Translation"), (LPVOID*)&pLangCP, (PUINT)&nTranslationLen);

		for(int ii = 0; ii < (nTranslationLen / sizeof(SLangCodePage)); ii++ )
		{
			AddTextToEdit(hEdit, _T("%-25s %0x04(%0x04)\r\n"), szVerItems[0], pLangCP[ii].wLanguage, pLangCP[ii].wCodePage);
			for (int jj = 1; jj < sizeof(szVerItems)/sizeof(*szVerItems); jj++)
			{
				TCHAR szSubBlock[MAX_PATH] = {0};
				_stprintf(szSubBlock, TEXT("\\StringFileInfo\\%04x%04x\\%s"), pLangCP[ii].wLanguage, pLangCP[ii].wCodePage, szVerItems[jj]);
				LPVOID szData = NULL;
				UINT dwBytes = 0;
				VerQueryValue(pszBlock, szSubBlock, &szData, &dwBytes);
				
				AddTextToEdit(hEdit, _T("%-25s %-20s\r\n"), szVerItems[jj], (TCHAR*)szData);
			}			
		}
		delete[] pszBlock;	
		FreeLibrary(hModule);
	}
	return;
}


int CALLBACK DlgProc(HWND hDlg, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	switch (nMsg)
	{
		case WM_INITDIALOG:
		{
			SetWindowText(hDlg, _T("Demo0086"));

			UINT nWidth		= GetSystemMetrics(SM_CXSCREEN);
			UINT nHeight	= GetSystemMetrics(SM_CYSCREEN);
			RECT rtClient;
			GetClientRect(hDlg, &rtClient);
			SetWindowPos(hDlg, NULL, (nWidth - (rtClient.right - rtClient.left)) / 2, (nHeight - (rtClient.bottom - rtClient.top)) / 2, 0, 0, SWP_NOSIZE);
			
			break;
		}
		case WM_DROPFILES:
		{
			HDROP hDrop = (HDROP)wParam;
			TCHAR szPath[MAX_PATH];
			DragQueryFile(hDrop, 0, szPath, MAX_PATH);
			if (0 != _tcslen(szPath) && -1 != GetFileAttributes(szPath))
			{
				SetWindowText(GetDlgItem(hDlg, IDC_STCPATH), szPath);
				SetWindowText(GetDlgItem(hDlg, IDC_EDTINFO), _T(""));
				DragFinish(hDrop);
			}
			
			break;
		}
		case WM_COMMAND:
		{
			switch (LOWORD(wParam))
			{
				case IDC_BTNVIEW:
				{
					TCHAR szModule[MAX_PATH];
					GetDlgItemText(hDlg, IDC_STCPATH, szModule, MAX_PATH);
					SetWindowText(GetDlgItem(hDlg, IDC_EDTINFO), _T(""));
					LoadModule(szModule, GetDlgItem(hDlg, IDC_EDTINFO));

					break;
				}
				case IDC_BTNBROWSE:
				{
					TCHAR szPath[MAX_PATH] = {0};
					OPENFILENAME ofn	= {0};
					ofn.lStructSize		= sizeof(ofn);
					ofn.Flags			= OFN_EXPLORER;
					ofn.hwndOwner		= hDlg;
					ofn.lpstrFilter		= _T("execute file(*.exe)\0*.exe\0");
					ofn.nMaxFile		= MAX_PATH;
					ofn.lpstrFile		= szPath;
					if (GetOpenFileName(&ofn))
					{
						SetWindowText(GetDlgItem(hDlg, IDC_STCPATH), szPath);
					}

					break;
				}
			}
			break;
		}
		case WM_CLOSE:
		{
			PostQuitMessage(0);
			break;
		}
	}

	return 0;
}

BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);

	return TRUE;
}